﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DIPLib
{
    public class SmoothingFilter
    {
        public static void doIt(byte[] rgbData, int width, int height, float[] magMatrix, byte edgeApproach)
        {
            MyBitmap bitmap = new MyBitmap(rgbData, width, height);
            byte[] rgbDataSrc = (byte[])rgbData.Clone();
            MyBitmap bitmapSrc = new MyBitmap(rgbDataSrc, width, height);
            int matrixSize = (int)Math.Sqrt(magMatrix.Length);

            byte[] matrix = new byte[matrixSize * matrixSize];

            int radius = matrixSize >> 1;
            if (edgeApproach == FilterUtils.ZERO_PADDING)
            {
                for (int row = 0; row < height; row++)
                {
                    for (int col = 0; col < width; col++)
                    {
                        // Fill the matrix
                        int c = 0;

                        for (int a = 0; a < matrixSize; a++)
                        {
                            bool defaultFill = false;
                            int ir = row + a - radius;
                            if (ir < 0 || ir >= height)
                            {
                                defaultFill = true;
                                // Ca 1 hang nam ngoai ma tran anh.
                            }
                            for (int b = 0; b < matrixSize; b++)
                            {
                                int jc = col + b - radius;
                                if (defaultFill == true)
                                {
                                    // Cot nay nam trong hang danh dau defaultFill 
                                    matrix[c++] = 0;
                                    continue;
                                }
                                // Neu thu tu cot nam trong ma tran anh, va hang cung nam trong ma tran anh
                                if (jc >= 0 && jc < width)
                                {
                                    matrix[c++] = bitmapSrc.getPixel(jc, ir);
                                    continue;
                                }
                                matrix[c++] = 0;
                            }
                        }
                        float sum = 0;
                        for (int index = 0; index < magMatrix.Length; index++)
                        {
                            sum += magMatrix[index] * matrix[index];
                        }
                        byte value = (byte)(sum < 0 ? 0 : (sum > 255 ? 255 : sum));
                        bitmap.setPixel(col, row, value);
                    }
                }
            }
            else if (edgeApproach == FilterUtils.REPLICATE)
            {
                for (int row = 0; row < height; row++)
                {
                    for (int col = 0; col < width; col++)
                    {
                        // Fill the matrix
                        int c = 0;

                        for (int a = 0; a < matrixSize; a++)
                        {
                            int ir = row + a - radius;

                            for (int b = 0; b < matrixSize; b++)
                            {
                                int jc = col + b - radius;

                                int useCol = jc;
                                int useRow = ir;

                                if (jc >= width)
                                {
                                    useCol = width - 1;
                                }
                                if (jc < 0)
                                {
                                    useCol = 0;
                                }

                                if (ir >= height)
                                {
                                    useRow = height - 1;
                                }
                                if (ir < 0)
                                {
                                    useRow = 0;
                                }

                                matrix[c++] = bitmapSrc.getPixel(useCol, useRow);
                            }
                        }

                        float sum = 0;
                        for (int index = 0; index < magMatrix.Length; index++)
                        {
                            sum += magMatrix[index] * matrix[index];
                        }
                        byte value = (byte)(sum < 0 ? 0 : (sum > 255 ? 255 : sum));
                        bitmap.setPixel(col, row, value);
                    }
                }
            }
        }
    }
}
